//Documentation complete
/**
 * @author Kazu
 * @version 2009MR22
 */

package problemDomain;

import static problemDomain.ErrorBean.throwError;
import static problemDomain.ErrorBean.ErrorCode.*;
import static utilities.XMLTools.encapsulateBeanListXML;
import static utilities.XMLTools.encodeEntities;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * A menu which contains menu items.
 */
public class MenuItemBean implements Bean {
	
	/* Constants */
	
	private static final long serialVersionUID = -2494951379212836258L;
	
	/* END Constants */
	
	
	/* Attributes */
	
	protected int id;
	protected MenuBean menu;
	protected String name;
	protected List<FoodItemBean> itemList;
	protected double price;
	protected int number;
	
	/* END Attributes */
	
	
	/* Constructors */
	
	/**
	 * Constructs a <code>MenuItemBean</code> with default values.
	 */
	public MenuItemBean () {
		this.id = 0;
		this.menu = null;
		this.name = "";
		this.price = 0.0;
		this.itemList = null;
		this.number = 0;
	}
	
	/**
	 * Constructs a <code>MenuItemBean</code> with an ID.
	 * @param id the ID of the menu item
	 */
	public MenuItemBean (int id) {
		this();
		this.id = id;
	}
	
	/**
	 * Constructs a <code>MenuItemBean</code> with specified values.
	 * @param id the ID of the menu item
	 * @param menu the menu that the menu item belongs to
	 * @param name the name of the menu item
	 * @param itemList the item list of the menu item
	 * @param price the price of the menu item
	 * @param number the list number of the menu item
	 */
	public MenuItemBean (int id, MenuBean menu, String name, List<FoodItemBean> itemList, double price, int number) {
		this.id = id;
		this.menu = menu;
		this.name = name;
		this.itemList = itemList;
		this.price = price;
		this.number = number;
	}
	
	/* END Constructors */
	
	
	/* Accessors */
	
	/**
	 * Returns the ID.
	 * @return the ID of the menu item
	 */
	public int getId () {
		return id;
	}
	
	/**
	 * Returns the menu.
	 * @return the menu that the menu item belongs to
	 */
	public MenuBean getMenu () {
		return menu;
	}
	
	/**
	 * Returns the name.
	 * @return the name of the menu item.
	 */
	public String getName () {
		return name;
	}
	
	/**
	 * Returns the item list. 
	 * @return the item list of the menu item
	 */
	public List<FoodItemBean> getItemList () {
		return itemList;
	}
	
	/**
	 * Returns the price.
	 * @return the price of the menu item
	 */
	public final double getPrice () {
		return price;
	}
	
	/**
	 * Returns the list number.
	 * @return the list number of the menu item
	 */
	public int getNumber () {
		return number;
	}
	
	/* END Accessors */
	
	
	/* Mutators */
	
	/**
	 * Sets the ID.
	 * @param id the ID of the menu item
	 */
	public void setId (int id) {
		this.id = id;
	}
	
	/**
	 * Sets the menu.
	 * @param menu the menu that the menu item belongs to
	 */
	public void setMenu (MenuBean menu) {
		this.menu = menu;
	}
	
	/**
	 * Sets the name.
	 * @param name the name of the menu item
	 */
	public void setName (String name) {
		this.name = name;
	}
	
	/**
	 * Sets the item list.
	 * @param itemList the item list of the menu item
	 */
	public void setItemList (List<FoodItemBean> itemList) {
		this.itemList = itemList;
	}
	
	/**
	 * Sets the list number.
	 * @param number the list number of the menu item
	 */
	public void setNumber (int number) {
		this.number = number;
	}
	
	/**
	 * Sets the price.
	 * @param price the price of the menu item
	 */
	public void setPrice (double price) {
		this.price = price;
	}
	
	/* END Mutators */
	
	
	/* Methods */
	
	/**
	 * Adds a food item to the menu item's item list.
	 * @param item the food item
	 */
	public void addItem (FoodItemBean item) {
		if (itemList == null)
			itemList = new ArrayList<FoodItemBean>();
		itemList.add(item);
	}
	
	/* END Methods */
	
	
	/* (Bean) Methods */
	
	@Override
	public boolean isValid () throws ErrorBean {
		//check if food items are valid too
		if (itemList != null) {
			Iterator<FoodItemBean> i = itemList.iterator();
			while (i.hasNext())
				i.next().isValid();
		}
		
		if (price < 0)
			throwError(
				MENUITEM_PRICE_INVALID,
				String.valueOf(price),
				this);
		
		if (id < 0)
			throwError(
				MENUITEM_ID_INVALID,
				String.valueOf(id),
				this);
		
		//if (menu != null)
		//	menu.isValid();
		
		if (name != null && name.equals(""))
			throwError(
				MENUITEM_NAME_INVALID,
				name,
				this);
		
		if (number < 0)
			throwError(
				MENUITEM_NUMBER_INVALID,
				String.valueOf(number),
				this);
		
		return true;
	}
	
	@Override
	public String toXML () {
		StringBuilder sb = new StringBuilder();
		sb.append("<menuitem>");
		sb.append("<id>" + id + "</id>");
		if (menu != null)
			sb.append("<menu-name>" + menu.getName() + "</menu-name>");
		else
			sb.append("<menu-name></menu-name>");
		sb.append("<menu-item-name>" + (name != null ? name : "") + "</menu-item-name>");
		sb.append("<price>" + price + "</price>");
		sb.append("<number>" + number + "</number>");
		sb.append(encapsulateBeanListXML(itemList, "fooditems"));
		sb.append("</menuitem>");
		return encodeEntities(sb.toString());
	}
	
	/* END (Bean) Methods */
	
	
	/* (Object) Methods */
	
	@Override
	public String toString () {
		StringBuilder sb = new StringBuilder();
		sb.append("ID: " + id + '\n');
		if (menu != null)
			sb.append(menu.toString());
		else
			sb.append("Menu is null.\n");
		sb.append("Name: " + name + '\n');
		sb.append("Price: " + price + '\n');
		sb.append("Item List:\n");
		if (itemList != null) {
			Iterator<FoodItemBean> i = itemList.iterator();
			while (i.hasNext())
				sb.append('\t' + i.next().toString().replaceAll("^(.*)$", "\t$1") + "\n");
		} else {
			sb.append("\tItem list is null.\n");
		}
		sb.append("Number: " + number + '\n');
		
		return sb.toString();
	}
	
	/* END (Object) Methods */
	
}
